﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

using System.Windows.Threading;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;

namespace ETRobocon.RaceTraking.GameManagement
{
    /// <summary>
    /// Interaction logic for GameSelecter.xaml
    /// </summary>
    [Export(typeof(ETRoboConTrakingSystem.ISwitchBoxClient))]
    //    [ExportMetadata("Status","Main")]
    public partial class GameSelecter : Window, ETRoboConTrakingSystem.ISwitchBoxClient, ISwitchLightStatusNotifier
    {
        private readonly CompositionContainer myContainer;

        private ETRoboConTrakingSystem.IRaceTrackingPresentation presentationWin;

        public GameSelecter()
        {
            InitializeComponent();
            // CurrentContainerをプロパティで渡す方法もあるが、カッコ悪いのでAppDomainを介して受け渡し
            // 引数付きコンストラクタを呼ぶ方法が判ればそれでも良い。
            myContainer = AppDomain.CurrentDomain.GetData("CurrentCompositionContainer") as CompositionContainer;
            // この例のように、クラスを介して生成する場合は、以下の様に、CompositionContainerでComposePartsをしなければならない。
            // このクラスにLazy<Type>型のプロパティを定義している場合には、ComposePartsはコールしなくてよい。
            // このクラスを含め、このクラスがインポートするタイプがインポートするタイプもLazy<Type>で全てImportしているものはここで確定する
            var preWinImporter = new PresentationWindowImporter();
            myContainer.ComposeParts(preWinImporter);
            presentationWin = preWinImporter.PresentationWin.Value;

            tmControl = new TopTurnControlWindow();
            // WSRound round = tmConsole.CurrentRound;
            WSRound round = tmControl.TMConsole.CurrentRound;

            rmConsole.CurrentRound = round;

            // rmConsole.InCourseBCPBuilder = tmConsole.InCourseBCPBuilder;
            // rmConsole.OutCourseBCPBuilder = tmConsole.OutCourseBCPBuilder;
            rmConsole.InCourseBCPBuilder = tmControl.TMConsole.InCourseBCPBuilder;
            rmConsole.OutCourseBCPBuilder = tmControl.TMConsole.OutCourseBCPBuilder;

            //       presenW = new ETRobocon.RaceTraking.GamePresentation.WindowPresentation();
            rmConsole.PresentationWindow = presentationWin;


            // tmConsole.PresentationWindow = presenW;
            tmControl.TMConsole.PresentationWindow = presentationWin;
            tmControl.TMConsole.LoadInCourseDifficultStatus();

            tmControl.TMConsole.OwnerWindow = tmControl;
           
            rmConsole.TurnCtrlWindow = tmControl;
        }

        //    private ETRobocon.RaceTraking.GamePresentation.WindowPresentation presenW;

        private long startTick;
        private TopTurnControlWindow tmControl;

        private SwitchLightStatus switchLightStatus;
        public SwitchLightStatus SwitchLightStatus
        {
            get { return switchLightStatus; }
            set
            {
                switchLightStatus = value;
                rmConsole.SwitchLightStatus = value;
                rmConsole.switchLightStatusNotifier = this;
                //  tmConsole.SwitchLightStatus = value;
                tmControl.TMConsole.SwitchLightStatus = value;
                tmControl.TMConsole.switchLightStatusNotifier = this;
            }
        }

        //        public delegate void NotifyPushedSwitchDelegator(ETRoboConTrakingSystem.SwitchBoxButtonType switchId, long tick);

        //        public void TryNotifyPushSwitch(ETRoboConTrakingSystem.SwitchBoxButtonType switchId, long tick)
        //        {
        //            this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
        //                new NotifyPushedSwitchDelegator(this.NotifyPushSwitch), switchId, tick);
        //        }

        #region ISwitchBoxClient Members

        public void SetDevice(ETRoboConTrakingSystem.ISwitchBoxDevice device)
        {
            device.OnButtonStatusChanged += new ETRoboConTrakingSystem.SwitchBoxButtonStatusChanged(device_OnButtonStatusChanged);
            this.SwitchLightStatus = new SwitchLightStatus();
        }

        void device_OnButtonStatusChanged(ETRoboConTrakingSystem.SwitchBoxButtonType buttonType, long tick)
        {
            TurnMgmtUserControl tm = tmControl.TMConsole;
            int duration = (int)(tick - startTick);
            switch (buttonType)
            {
                case ETRoboConTrakingSystem.SwitchBoxButtonType.START:
                    startTick = tick;
                    tm.NotifyRunningStart();
                    break;
                case ETRoboConTrakingSystem.SwitchBoxButtonType.RESET:
                    tm.NotifyRunningStop();
                    break;
                case ETRoboConTrakingSystem.SwitchBoxButtonType.GOAL_IN:
                    tm.NotifyGoaled(WSRunner.CourseName.IN, duration);
                    break;
                case ETRoboConTrakingSystem.SwitchBoxButtonType.RETIRE_IN:
                    tm.NotifyRetired(WSRunner.CourseName.IN, duration);
                    break;
                case ETRoboConTrakingSystem.SwitchBoxButtonType.GOAL_OUT:
                    tm.NotifyGoaled(WSRunner.CourseName.OUT, duration);
                    break;
                case ETRoboConTrakingSystem.SwitchBoxButtonType.RETIRE_OUT:
                    tm.NotifyRetired(WSRunner.CourseName.OUT, duration);
                    break;
            }

        }

        public event ETRoboConTrakingSystem.SwitchBoxLEDStatus OnSwitchBoxLEDStatusChanged;

        #endregion

        #region ISwitchLightStatusNotifier Members

        public void Update(SwitchLightStatus sls)
        {
            if (OnSwitchBoxLEDStatusChanged != null)
            {
                OnSwitchBoxLEDStatusChanged(
            start: sls.StartSwitch,
            reset: sls.ResetSwitch,
            goalIn: sls.GoalInSwitch,
            retireIn: sls.RetireInSwitch,
            goalOut: sls.GoalOutSwitch,
            retierOut: sls.RetireOutSwitch);
            }
        }

        public void Reset()
        {
            if (OnSwitchBoxLEDStatusChanged != null)
            {
                OnSwitchBoxLEDStatusChanged(false, false, false, false, false, false);
            }
        }

        #endregion
    }

    public class PresentationWindowImporter
    {
        [Import(typeof(ETRoboConTrakingSystem.IRaceTrackingPresentation))]
        public Lazy<ETRoboConTrakingSystem.IRaceTrackingPresentation> PresentationWin { get; set; }
    }
}
